package net.simflow.swf.analyzer.graph.opt;

import java.util.Collection;

import net.simflow.swf.analyzer.network.data.Flow;
import net.simflow.swf.analyzer.network.data.Link;
import net.simflow.swf.analyzer.network.data.Network;
import net.simflow.swf.analyzer.network.data.Node;

import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.graph.Graph;

public class GraphMaker {

	private static GraphMaker instance = new GraphMaker();

	private GraphMaker() {
	}

	public static GraphMaker getInstance() {
		return instance;
	}

	public Graph<Node, Link> make(Network network) {
		if (network.getNodeSet().isEmpty()) {
			return null;
		}
		return make(network.getNodeSet(), true);
	}

	public Graph<Node, Link> make(Network network, boolean hashAcnode) {
		if (network.getNodeSet().isEmpty()) {
			return null;
		}
		return make(network.getNodeSet(), hashAcnode);
	}

	public Graph<Node, Link> make(Flow flow) {
		if (flow.getNodeSet().isEmpty()) {
			return null;
		}
		return make(flow.getNodeSet(), true);
	}

	public Graph<Node, Link> make(Flow flow, boolean hasAcnode) {
		if (flow.getNodeSet().isEmpty()) {
			return null;
		}
		return make(flow.getNodeSet(), hasAcnode);
	}

	private Graph<Node, Link> make(Collection<? extends Node> nodes,
			boolean hasAcnode) {
		Graph<Node, Link> g = new DirectedSparseGraph<Node, Link>();

		for (Node n : nodes) {
			if (!hasAcnode) {
				if (n.getChildControlSet().isEmpty()
						&& n.getChildDataSet().isEmpty()
						&& n.getParentControlSet().isEmpty()
						&& n.getParentDataSet().isEmpty()) {
					continue;
				}
			}
			g.addVertex(n);
		}

		for (Node p : g.getVertices()) {
			for (Node c : p.getChildDataSet()) {
				g.addEdge(new Link(p, c, false), p, c);
			}
			for (Node c : p.getChildControlSet()) {
				g.addEdge(new Link(p, c, true), p, c);
			}
		}

		return g;
	}
}
